#ifndef AutoHideSideBarH
#define AutoHideSideBarH
/*******************************************************************************
** Qt Advanced Docking System
** Copyright (C) 2017 Uwe Kindler
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with this library; If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/


//============================================================================
/// \file   AutoHideSideBar.h
/// \author Syarif Fakhri
/// \date   05.09.2022
/// \brief  Declaration of CAutoHideSideBar class
//============================================================================

//============================================================================
//                                   INCLUDES
//============================================================================
#include <QScrollArea>
#include "ads_globals.h"
#include "AutoHideTab.h"

class QXmlStreamWriter;

namespace ads
{
    struct AutoHideSideBarPrivate;
    class DockContainerWidgetPrivate;
    class CDockContainerWidget;
    class CAutoHideTab;
    class CAutoHideDockContainer;
    class CDockingStateReader;

    /**
     * 边栏选项卡小部件，显示在停靠容器的边缘。
     * 只有在包含可见内容（即可见选项卡）时，选项卡栏才可见。
     * 如果为空或所有选项卡都隐藏，则边栏也将隐藏。
     * 一旦有一个单独的选项卡变为可见，该选项卡栏将显示。
     * CAutoHideSideBar 在这里使用 QScrollArea，以实现适当的调整大小。
     * 如果边栏包含许多选项卡，则选项卡将被简单地裁剪 - 这与 Visual Studio 相同。
     */
    class ADS_EXPORT CAutoHideSideBar : public QScrollArea
    {
        Q_OBJECT
        Q_PROPERTY(int sideBarLocation READ sideBarLocation)
        Q_PROPERTY(Qt::Orientation orientation READ orientation)
        Q_PROPERTY(int spacing READ spacing WRITE setSpacing)

    private:
        AutoHideSideBarPrivate* d; ///< 私有数据 (pimpl)
        friend struct AutoHideSideBarPrivate;
        friend class DockWidgetSideTab;
        friend DockContainerWidgetPrivate;
        friend CDockContainerWidget;

    protected:
        virtual bool eventFilter(QObject *watched, QEvent *event) override;

        /**
         * 将状态保存到给定的流中
         */
        void saveState(QXmlStreamWriter& Stream) const;

        /**
         * 在给定位置插入指定的停靠窗口选项卡。
         * Index 值为 -1 时将选项卡追加到末尾。
         */
        void insertTab(int Index, CAutoHideTab* SideTab);

    public:
        using Super = QScrollArea;

        /**
         * 默认构造函数
         */
        CAutoHideSideBar(CDockContainerWidget* parent, SideBarLocation area);

        /**
         * 虚析构函数
         */
        virtual ~CAutoHideSideBar();

        /**
         * 从选项卡栏中移除指定的 DockWidgetSideTab
         */
        void removeTab(CAutoHideTab* SideTab);

        /**
         * 在边栏中插入停靠窗口。
         * 该函数创建自动隐藏停靠容器，插入自动隐藏选项卡
         */
        CAutoHideDockContainer* insertDockWidget(int Index, CDockWidget* DockWidget);

        /**
         * 从此边栏中移除自动隐藏小部件
         */
        void removeAutoHideWidget(CAutoHideDockContainer* AutoHideWidget);

        /**
         * 将给定的 AutoHideWidget 添加到此边栏。
         * 如果 AutoHideWidget 在其他边栏中，则将其从其他边栏中移除。
         */
        void addAutoHideWidget(CAutoHideDockContainer* AutoHideWidget, int Index = TabDefaultInsertIndex);

        /**
         * 返回边栏选项卡的方向。
         */
        Qt::Orientation orientation() const;

        /**
         * 获取指定位置的边栏选项卡小部件，如果超出范围则返回 nullptr
         */
        CAutoHideTab* tab(int index) const;

        /**
         * 返回给定位置的选项卡。
         * 如果位置在第一个选项卡的左侧，则返回 -1；
         * 如果位置在最后一个选项卡的右侧，则返回 count()；
         * 如果位置无效，则返回 InvalidTabIndex (-2)。
         */
        int tabAt(const QPoint& Pos) const;

        /**
         * 返回给定鼠标光标位置的选项卡插入索引
         */
        int tabInsertIndexAt(const QPoint& Pos) const;

        /**
         * 返回给定选项卡的索引
         */
        int indexOfTab(const CAutoHideTab& Tab) const;

        /**
         * 获取选项卡小部件的数量
         */
        int count() const;

        /**
         * 返回其父窗口中可见选项卡的数量
         */
        int visibleTabCount() const;

        /**
         * 如果边栏中包含对父窗口可见的选项卡，则返回 true。
         * 该函数在找到第一个可见选项卡后立即返回。
         * 这意味着，如果只想知道是否有可见选项卡，那么该函数比 visibleTabCount() 更快。
         */
        bool hasVisibleTabs() const;

        /**
         * 获取边栏选项卡的位置
         */
        SideBarLocation sideBarLocation() const;

        /**
         * 重写 QScrollArea 的 minimumSizeHint() 函数。
         * minimumSizeHint() 的大小比 sizeHint() 大，因为即使滚动条不可见，minimumSizeHint() 中仍然保留了所需的空间。
         * 此重写只是简单地返回 sizeHint()。
         */
        virtual QSize minimumSizeHint() const override;

        /**
         * 该函数提供与内部视口的高度相匹配的 sizeHint。
         */
        virtual QSize sizeHint() const override;

        /**
         * 获取间距属性的值 - 返回选项卡之间的间距
         */
        int spacing() const;

        /**
         * 设置间距属性的值 - 设置选项卡之间的间距
         */
        void setSpacing(int Spacing);

        /**
         * 返回承载此边栏的停靠容器
         */
        CDockContainerWidget* dockContainer() const;
    };
} // namespace ads
//-----------------------------------------------------------------------------
#endif
